package Day012_多线程2.demo01_synchronized关键字;

/**
 * @author zhangyan
 * @date 2020/4/30 9:38
 */
/*
    synchronized关键字：表示“同步”的。

                    synchronized(同步锁){
                         需要同步操作的代码
                    }

    它可以对“多行代码”进行“同步”——将多行代码当成是一个完整的整体，一个线程如果进入到这个代码块中，会全部执行完毕，执行结束后，其它线程才会执行。
    这样可以保证这多行的代码作为完整的整体，被一个线程完整的执行完毕。

    synchronized有几种使用方式：
                            a).修饰代码块,同步代码块
                            b).修饰方法,同步方法【常用】

    synchronized被称为“重量级的锁”方式，也是“悲观锁”——效率比较低。
    cas机制称为乐观锁

    注意:
        锁对象可以使任意对象
        多条线程要想实现同步,那么锁对象必须一致

 */

public class demo02_同步代码块 {

    static Object lock = new Object();

    public static void main(String[] args) {
        //创建线程任务对象
        MyRunnable1 mr = new MyRunnable1();
        //创建三个窗口对象
        Thread t1 = new Thread(mr, "窗口1");
        Thread t2 = new Thread(mr, "窗口2");
        Thread t3 = new Thread(mr, "窗口3");
        //同时卖票
        t1.start();
        t2.start();
        t3.start();
    }
}

class MyRunnable1 implements Runnable {
    int ticket = 100;

    public void run() {
        //每个窗口卖票的操作
        //死循环卖票
        while (true) {
            //票卖完,就结束循环
            //synchronized (new Object()) {
            synchronized (demo02_同步代码块.lock) {  // this == mr,多条线程要想实现同步,那么锁对象必须一致
                if (ticket < 1) {
                    break;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //获取当前线程对象的名字
                String name = Thread.currentThread().getName();
                System.out.println(name + "正在卖第:" + ticket + "张票");
                ticket--;
            }
            //释放锁
        }
    }
}
